package Engine.RMI
{
    import Framework.Serialize.*;
    import Framework.Util.*;

    public class Outgoing extends Object
    {

        public function Outgoing()
        {
        }

        public static function dispatch(context:Context, srmiReturn:SRMIReturn, stream:SerializeStream) : Boolean
        {
            if (!context._connection)
            {
                return false;
            }
            var istream:* = new SerializeStream();
            ERMIMessageType.MessageTypeCallRet.__write(istream);
            srmiReturn.__write(istream);
			istream.writeByteArray(stream);
            return context._connection.send(istream.byteArray) != -1;
        }

        public static function invokeAsync(context:Context, operation:SRMICall, stream:SerializeStream, rmiObj:RMIObject) : void
        {
            var exception:Exception;
            if (context._session.communicator == null)
            {
				exception = new Exception("ExceptionCodeNotInstantiation", RMIException.ExceptionCodeNotInstantiation);
				rmiObj.cdeException(exception);
                
            }
            var commandHandler:IRMIPrepareCommandHandler = context._session.communicator.prepareCommandHandler;
            if (commandHandler != null)
            {
                if (!commandHandler.prepareCommand(operation, context, rmiObj))
                {
                    
                }
            }
            if (rmiObj == null)
            {
                invokeAsyncNoBack(context, operation, stream);
            }
            else
            {
                invokeAsyncBack(context, operation, stream, rmiObj);
            }
        }

        private static function invokeAsyncBack(context:Context, operation:SRMICall, stream:SerializeStream, rmiObj:RMIObject) : void
        {
            var exception:Exception = null;
            var rmiObjBind:* = new RMIObjectBind();
            rmiObj.identity = operation.identity;
            rmiObjBind.messageId = context._session.addBackObject(rmiObjBind, context._timeOut);
            rmiObjBind.rmiObject = rmiObj;
            rmiObjBind.outgoingStatus = RMIObjectBind.EOutGoingWaitToSend;
            rmiObjBind.session = context._session;
            var stream:* = new SerializeStream();
            ERMIMessageType.MessageTypeCall.__write(stream);
            operation.callSynchType = ERMICallModel.CallModelAsync;
            operation.messageId = rmiObjBind.messageId;
            if (operation.messageId <= 0)
            {
                exception = new Exception("Outgoing::context._session.addBackObject exception", Exception.ExceptionCodeBase);
                rmiObj.cdeException(exception);
            }
            operation.__write(stream);
            stream.writeByteArray(stream);
            if (context._connection == null)
            {
				context._connection = context._session.connection;
            }
            rmiObjBind.buffer = stream;
            if (context._connection == null)
            {
                if (context._session.communicator && !context._session.communicator.connecting)
                {
                    if (context._session.communicator.connect())
                    {
						context._session.addMessage(rmiObjBind);
                        
                    }
                }
                else
                {
					context._session.addMessage(rmiObjBind);
                }
            }
            else if (context._connection.send(stream.byteArray) == -1)
            {
				context._session.findRemoveBackObject(operation.messageId);
                exception = new RMIException("Outgoing::context._connection.send exception", RMIException.ExceptionCodeConnectionWrite);
                rmiObj.cdeException(exception);
            }
        }

        public static function invokeAsyncNoBack(context:Context, call:SRMICall, stream:SerializeStream) : void
        {
            var rmiObjBind:* = new RMIObjectBind();
            new RMIObjectBind().messageId = 0;
			rmiObjBind.rmiObject = null;
			rmiObjBind.outgoingStatus = RMIObjectBind.EOutGoingWaitToSend;
            var stream:* = new SerializeStream();
            if (context._messageType && context._messageType.equals(ERMIMessageType.MessageTypeMQ))
            {
                context._messageType.__write(stream);
            }
            else
            {
                ERMIMessageType.MessageTypeCall.__write(stream);
                call.messageId = 0;
                call.callSynchType = ERMICallModel.CallModelAsync;
                call.__write(stream);
            }
            stream.writeByteArray(stream);
            if (context._connection == null)
            {
                context._connection = context._session.connection;
            }
            if (context._connection == null)
            {
                if (!context._session.communicator.connecting)
                {
                    if (context._session.communicator.connect())
                    {
						rmiObjBind.buffer = stream;
                        context._session.addMessage(rmiObjBind);
                        
                    }
                }
            }
            else
            {
                context._connection.send(stream.byteArray);
            }
        }
    }
}
